﻿using System;
using SystemArray =System.Array;
using Map;
using Microsoft.Xna.Framework;

namespace Map_Creator.MapInfo
{
    public class AutoTile4 : AutoTile4Struct
    {
        private short realValue;
        public override short Value
        {
            get
            {
                return realValue;
            }
        }

        public AutoTile4(AutoTileData aData)
        {
            if (aData.Type != AutoTileType.AutoTile4)
                throw new Exception("Bad AutoTileData Type");

            Type = TileType.Auto4;

            AutoData = aData;

            var goodTile = SystemArray.Find(AutoData.Tiles, t => t != null);

            realValue = goodTile.Value;
            TileSetIndex = goodTile.TileSetIndex;
        }

        /// <summary>
        /// Checks the Buttom Right corner for same autotiles neighbors
        /// </summary>
        /// <param name="grid">The Edited Grid</param>
        /// <param name="pos">The Position</param>
        /// <returns>True if Ok</returns>
        bool CheckCorner(TileStructGrid grid, Point pos)
        {
            var tileRight = grid[pos.X + 1, pos.Y] as AutoTile4;
            if (tileRight == null || tileRight.AutoData != AutoData)
                return false;

            var tileDown = grid[pos.X, pos.Y + 1] as AutoTile4;
            if (tileDown == null || tileDown.AutoData != AutoData)
                return false;

            var tileDownRight = grid[pos.X + 1, pos.Y + 1] as AutoTile4;
            if (tileDownRight == null || tileDownRight.AutoData != AutoData)
                return false;

            var tile = grid[pos.X, pos.Y] as AutoTile4;
            if (tile == null || tile.AutoData != AutoData)
                return false;

            return true;
        }

        /// <summary>
        /// Checks the Buttom Right corner for same autotiles neighbors
        /// </summary>
        /// <param name="grid">The Edited Grid</param>
        /// <param name="pos">The  Position</param>
        /// <returns>True if Ok</returns>
        bool CheckTile(TileStructGrid grid, Point pos)
        {
            var tile = grid[pos] as AutoTile4;
            if (tile == null || tile.AutoData != AutoData)
                return false;

            return true;
        }

        public override void UpdateValue(TileStructGrid grid, Point pos, bool Recurse = true)
        {
            AutoTile4Corners newCorners = 0;

            // UpLeft
            if (pos.X > 0 && pos.Y > 0)
            {
                if (CheckCorner(grid, new Point(pos.X - 1, pos.Y - 1)))
                    newCorners |= AutoTile4Corners.UpLeft;
            }
            else
            {
                if (pos.X != 0)
                {
                    if (CheckTile(grid, new Point(pos.X - 1, pos.Y)))
                        newCorners |= AutoTile4Corners.UpLeft;
                }
                else if (pos.Y != 0)
                {
                    if (CheckTile(grid, new Point(pos.X, pos.Y - 1)))
                        newCorners |= AutoTile4Corners.UpLeft;
                }
                else
                {
                    newCorners |= AutoTile4Corners.UpLeft;
                }
            }

            // UpRight
            if (pos.X < grid.Size.X - 1 && pos.Y > 0)
            {
                if (CheckCorner(grid, new Point(pos.X, pos.Y - 1)))
                    newCorners |= AutoTile4Corners.UpRight;
            }
            else
            {
                if (pos.X != grid.Size.X - 1)
                {
                    if (CheckTile(grid, new Point(pos.X + 1, pos.Y)))
                        newCorners |= AutoTile4Corners.UpRight;
                }
                else if (pos.Y != 0)
                {
                    if (CheckTile(grid, new Point(pos.X, pos.Y - 1)))
                        newCorners |= AutoTile4Corners.UpRight;
                }
                else
                {
                    newCorners |= AutoTile4Corners.UpRight;
                }
            }

            // DownLeft
            if (pos.X > 0 && pos.Y < grid.Size.Y - 1)
            {
                if (CheckCorner(grid, new Point(pos.X - 1, pos.Y)))
                    newCorners |= AutoTile4Corners.DownLeft;
            }
            else
            {
                if (pos.X != 0)
                {
                    if (CheckTile(grid, new Point(pos.X - 1, pos.Y)))
                        newCorners |= AutoTile4Corners.DownLeft;
                }
                else if (pos.Y != grid.Size.Y - 1)
                {
                    if (CheckTile(grid, new Point(pos.X, pos.Y + 1)))
                        newCorners |= AutoTile4Corners.DownLeft;
                }
                else
                {
                    newCorners |= AutoTile4Corners.DownLeft;
                }
            }

            // DownRight
            if (pos.X < grid.Size.X - 1 && pos.Y < grid.Size.Y - 1)
            {
                if (CheckCorner(grid, new Point(pos.X, pos.Y)))
                    newCorners |= AutoTile4Corners.DownRight;
            }
            else
            {
                if (pos.X != grid.Size.X - 1)
                {
                    if (CheckTile(grid, new Point(pos.X + 1, pos.Y)))
                        newCorners |= AutoTile4Corners.DownRight;
                }
                else if (pos.Y != grid.Size.Y - 1)
                {
                    if (CheckTile(grid, new Point(pos.X, pos.Y + 1)))
                        newCorners |= AutoTile4Corners.DownRight;
                }
                else
                {
                    newCorners |= AutoTile4Corners.DownRight;
                }
            }

            if (AutoData[(int)newCorners] == null)
                realValue = -1;
            else
                realValue = AutoData[(int)newCorners].Value;
            Corners = newCorners;

            base.UpdateValue(grid,pos,Recurse);
        }
    }
}